home *** CD-ROM | disk | FTP | other *** search
- package sub_arctic.lib;
- import sub_arctic.input.*;
- import sub_arctic.lib.sub_arctic_error;
- import sub_arctic.constraints.constraint;
- import sub_arctic.output.style;
- import sub_arctic.output.style_manager;
- import sub_arctic.output.drawable;
- import java.awt.Font;
-
- /**
- * This class implements a columnar menu. It expects to popped up
- * and down based on input from the menu_focus_agent. This object
- * also holds the reference to the menu_focus_agent in a static
- * variable. <p>
- *
- * You can put any interactor in this object as a child, but only
- * things which are subclasses of menu_item will get the highlight
- * behavior and get notified when they are selected. Thus it is
- * useful to put labels or spacers in this object to decorate your
- * menu.
- *
- * @author Ian Smith
- */
- public class menu extends column implements menu_focusable {
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Construct a menu. This version assumes you want to use the style
- * system's beveling routines to figure out your spacing.
- * @param int xv x position of this interactor
- * @param int yv y position of this interactor
- */
- public menu(int x, int y)
- {
- // XXX assumes that the beveling of the style is symmetrical
- // XXX in X and Y
- super(style_manager.current_style().drawable_horizontal_space(),
- 0,false,false,column.LEFT_JUSTIFIED);
- set_x(x);
- set_y(y);
- set_selected_item(-1);
- set_visible(false);
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Construct a menu. This version assumes you want to use the style
- * system's beveling routines to figure out your spacing.
- * @param int xv x position of this interactor
- * @param int yv y position of this interactor
- * @param callback_object co the object to send callbacks to
- */
- public menu(int x, int y, callback_object co)
- {
- // XXX assumes that the beveling of the style is symmetrical
- // XXX in X and Y
- super(style_manager.current_style().drawable_horizontal_space(),
- 0,false,false,column.LEFT_JUSTIFIED);
- _callback_obj=co;
- set_x(x);
- set_y(y);
- set_selected_item(-1);
- set_visible(false);
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Construct a menu. This version assumes you want to use the style
- * system's beveling routines to figure out your spacing and
- * the constraint system to do your placement.
- *
- * @param callback_object co the object to send callbacks to
- */
- public menu(callback_object co)
- {
- // XXX assumes that the beveling of the style is symmetrical
- // XXX in X and Y
- super(style_manager.current_style().drawable_horizontal_space(),
- 0,false,false,column.LEFT_JUSTIFIED);
- _callback_obj=co;
- set_selected_item(-1);
- set_visible(false);
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Construct a menu. This version assumes you want to use the style
- * system's beveling routines to figure out your spacing and
- * the constraint system to do your placement.
- *
- */
- public menu()
- {
- // XXX assumes that the beveling of the style is symmetrical
- // XXX in X and Y
- super(style_manager.current_style().drawable_horizontal_space(),
- 0,false,false,column.LEFT_JUSTIFIED);
- set_selected_item(-1);
- set_visible(false);
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * This holds the callback object.
- */
- callback_object _callback_obj=null;
-
- /**
- * Get the value of the current callback object.
- * @return callback_object the current object who gets the callbacks of this
- * menu.
- */
- callback_object callback_obj() { return _callback_obj;};
-
- /**
- * Change the value of the current callback object.
- * @param callback_object c the new callback object.
- */
- void set_callback_obj(callback_object c) { _callback_obj=c;};
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * This function gets called during the process of the user
- * dragging around on the menu. The menu should probably
- * use pick() to figure out who to highlight based on this
- * event. We ignore the user_info for now.
- *
- * @param event evt the event causing the feedback.
- * @param Object user_info (not used) this is the object we passed to the
- * menu_focus_agent when we made ourselves the focus.
- */
- public void menu_feedback(event evt,Object user_info ) {
- pick_collector pc=new pick_collector();
- int i,index;
- user_info_holder uih;
- menu_item mi;
-
- /* run a pick on the location */
- pick(evt.local_x(), evt.local_y(), pc);
-
- /* loop over everything picked */
- for (i=0;i<pc.num_picks(); ++i) {
-
- /* grab the ith and see if its a menu item */
- uih=pc.pick(i);
- if (uih.obj instanceof menu_item) {
- index=find_child(uih.obj);
-
- /* if the index is -1, there might be one of our children
- later on... in particular, the -1 child might be a child
- of one of our children */
- if (index==-1) continue;
-
- /* if its already selected don't bother */
- if (index==selected_item()) return;
-
- /* if somebody else needs to be unhighlighted, unless nobody
- is selected */
- if (selected_item()!=-1) {
- mi=(menu_item)child(selected_item());
- mi.unhighlight(evt);
- }
-
- /* tell this guy he's selected */
- mi=(menu_item)child(index);
- mi.highlight(evt);
- set_selected_item(index);
- }
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** Callback constant number for menu selection callback */
- public static final int MENU_SELECT_CALLBACK = 0;
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * This function gets called to inform you that the mouse button
- * was released over your menu. Again, no use of user_info for now.
- *
- * @param event evt the event which terminated the interactor
- * (probably a mouse up).
- * @param Object user_info (not used) the object we passed to the
- * menu_focus_agent when we put ourselves into the
- * menu focus.
- */
- public void menu_release(event evt, Object user_info) {
- int i,index;
- user_info_holder uih;
- pick_collector pc=new pick_collector();
-
- /* run a pick on the location */
- pick(evt.local_x(), evt.local_y(), pc);
-
- /* loop over everything picked */
- for (i=0;i<pc.num_picks(); ++i) {
-
- /* grab the ith and see if its a menu item */
- uih=pc.pick(i);
- if (uih.obj instanceof menu_item) {
- index=find_child(uih.obj);
-
- /* is it not one of our children? */
- if (index==-1) return;
-
- /* got the winner ... look for a callback object */
- if (callback_obj()!=null) {
- callback_obj().callback(this,evt,MENU_SELECT_CALLBACK,child(index));
-
- }
- }
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * This function gets called to inform you that you have been put into
- * the focus set (in this case the menu_focus_agent is the agent
- * whose set you are in). We pop up (display) the menu at this point.
- *
- * @param event cause_event the event that caused you to enter the focus set
- * @param focus_dispatch_agent of_agent this is the agent whose set you have
- * been added to (we ignore this right
- * now).
- * @param Object user_info the object you passed to the agent
- * when you asked to enter the set (we
- * ignore this right now).
- */
- public void focus_set_enter(event cause_evt,
- focus_dispatch_agent of_agent /* ignored */,
- Object user_info /* ignored */) {
- menu_item mi;
- /* initially there is nobody selected */
- if (selected_item()!=-1) {
- mi=(menu_item)child(selected_item());
- mi.unhighlight(cause_evt);
- }
- set_selected_item(-1);
- set_visible(true);
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * This is called when the menu leaves the focus set. We use it
- * pop-down (remove from the display) the menu. We do this because
- * we know that the "active" menus with respect to the
- * menu_focus_agent (the one's the user is interacting with) are
- * always kept in the focus set.
- *
- * @param event cause_event the event that caused you to exit
- * the focus set.
- * @param focus_dispatch_agent of_agent this is the agent whose set you
- * have just left (we ignore this
- * right now).
- * @param Object user_info the object you passed to the agent
- * when you asked to enter the set
- * (we ignore this right now).
- */
- public void focus_set_exit(event cause_evt,
- focus_dispatch_agent of_agent /* ignored */,
- Object user_info /* ignored */){
- menu_item mi;
- set_visible(false);
-
- /* possibly tell people to not be in highlighted state across
- runs */
- if (selected_item()!=-1) {
-
- /* tell him to go off */
- mi=(menu_item)child(selected_item());
- mi.unhighlight(cause_evt);
- set_selected_item(-1);
-
- /* remove us from the parent */
- parent().remove_child(this);
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Value, get & set functions for the selected item. This is
- * -1 when nothing is selected.
- */
- protected int _selected_item;
-
- /**
- * Return the currently selected item's number. You will get -1
- * when nothing is selected.
- *
- * @return int the currently selected item's number
- */
- public int selected_item() { return _selected_item;};
-
- /**
- * Change the currently selected item.
- * @param int v the new selected item (use -1 for no selected item)
- */
- public void set_selected_item(int v) { _selected_item=v;};
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * This holds the menu focus agent which is only used by the
- * menu code.
- */
- static menu_focus_agent _agent;
-
- /**
- * Return the menu_focus_agent.
- * @param menu_focus_agent the system's menu_focus_agent.
- */
- static public menu_focus_agent agent() {return _agent;};
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /*
- * static initializer to set up the agent.
- */
- static {
- _agent=new menu_focus_agent();
- manager.focus_policy.add_agent_after(_agent,null);
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * This gets called to tell us that the pointer has left us. We
- * just reset our state to not having anything selected.
- *
- * @param event evt the event that caused us to be exited (probably a
- * mouse movement).
- * @param Object user_info the object you passed to the agent when you asked
- * to enter the set (we ignore this right now).
- */
- public void menu_exit(event evt, Object user_info /* ignored */) {
-
- if (selected_item()!=-1) {
- /* we had a selection... send the unhighlight command */
- ((menu_item)child(selected_item())).unhighlight(evt);
-
- /* reset to no selection */
- set_selected_item(-1);
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * This gets called to ask us what child would result from
- * this point. This is used by the menu_focus_agent to determine
- * if the user is "pointing at" another pullright which would
- * result in a different menu being popped up from the one that
- * is currently popped up.
- *
- * @param int local_x the x coordinate in question in our coordinate system
- * @param int local_y the y coordinate in question in our coordinate system
- */
- public menu menu_generates_submenu(int local_x, int local_y) {
- int i,index;
- user_info_holder uih;
- pick_collector pc=new pick_collector();
-
- /* run a pick on the location */
- pick(local_x,local_y, pc);
-
- /* loop over everything picked */
- for (i=0;i<pc.num_picks(); ++i) {
-
- /* grab the ith and see if its a menu item */
- uih=pc.pick(i);
- if (uih.obj instanceof pullright_menu_item) {
-
- /* which child is it? */
- index=find_child(uih.obj);
-
- /* is it not one of our children? */
- if (index==-1) continue;
-
- /* return the menu of this item */
- return (((pullright_menu_item)child(index)).pullright());
- }
- }
-
- /* couldn't find a menu */
- return null;
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * This is a special version of draw self local to allow us to
- * give the object a raised look.
- * @param drawable d the surface to draw on.
- */
- public void draw_self_local(drawable d)
- {
- style cs=style_manager.current_style();
-
- cs.drawable_prepare_rect(d,0,0,w(),h(),true, true);
- draw_children(d);
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * This is a convenience function for creating a simple menu from
- * text strings in some font.
- *
- * @param String[] value the array of strings to place on the menu
- * @param Font f the font to build the menu items in (if you
- * pass null you will get the system default
- * font).
- * @param callback_object co the object to send the callbacks to
- * @return menu a menu with a set of text_menu_items in it (one for each
- * string)
- */
- static public menu create_text_menu(
- String[] value,
- Font f,
- callback_object co)
- {
- Font font;
- menu m=new menu(co);
- int max,i;
-
- /* set the font up */
- if (f==null) {
- font=style_manager.default_font();
- } else {
- font=f;
- }
-
- /* find out the largest one */
- max=text_menu_item.max_item_width(value,font);
-
- /* loop over the strings */
- for (i=0; i<value.length; ++i) {
- m.add_child(new text_menu_item(value[i],max));
- }
-
- /* we're done */
- return m;
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- }
- /*=========================== COPYRIGHT NOTICE ===========================
-
- This file is part of the subArctic user interface toolkit.
-
- Copyright (c) 1996 Scott Hudson and Ian Smith
- All rights reserved.
-
- The subArctic system is freely available for most uses under the terms
- and conditions described in
- http://www.cc.gatech.edu/gvu/ui/sub_arctic/sub_arctic/doc/usage.html
- and appearing in full in the lib/interactor.java source file.
-
- The current release and additional information about this software can be
- found starting at: http://www.cc.gatech.edu/gvu/ui/sub_arctic/
-
- ========================================================================*/
-